<html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-2">
<title>Design Philosophy Behind Motorola's MC68000 (3)</title></head><body>
<center>
<script type="text/javascript"><!--
	google_ad_client = "pub-0565437031849443";
	/* 728x90, Paulrsm */
	google_ad_slot = "7189181649";
	google_ad_width = 728;
	google_ad_height = 90;
	//-->
</script>
<script style="display: none;" type="text/javascript" src="dpbm68k3_pliki/show_ads.js">
</script>
<p>
</p></center>
<font size="4"><a href="http://www.easy68k.com/index.html">EASy68K Home</a>
</font>

<h1>Design Philosophy Behind Motorola's MC68000</h1>
<h2>Part 3: Advanced instructions</h2>
<p>June 1983 &#169; BYTE Publications Inc</p>
<p>Thomas W. Starnes<br>Motorola Inc., Microprocessor Division<br>3501 Ed Bluestein Blvd.<br>Austin, TX 78721</p>
<p>Last month (May BYTE, page 342), I discussed the data-movement,
arithmetic, and logic instructions of Motorola's MC68000 family of
microprocessors (sometimes referred to as MACSS -- Motorola's Advanced
Computer System on Silicon). I examined a useful set of instructions
based on a philosophy of <i>orthogonality</i>, which eliminates
duplication of effort by similar instructions (thus making the
microprocessor easier to understand and use). In this final part of the
series, I will discuss branching, jumping, error-trapping,
supervisor-mode, and other advanced instructions of the MC68000.</p>
<h3>Branching and Jumping</h3>
<p>Data-movement, arithmetic, and logic instructions do most of the
computational work in programs, but computers would be little more than
adding machines without <i>program-control instructions</i>. These
instructions give computers the capability to make decisions by
executing nonsequential areas of code based on conditions tested at the
time of execution. Branch instructions enable the microprocessor to
transfer control to portions of code relative to the instruction being
executed -- that is, to transfer control to the effective address,
which is the sum of the current contents of the program counter and a
given offset. You use branch instructions extensively when writing
position-independent code. Jump instructions differ from branch
instructions in that the jump instructions transfer control to absolute
locations in memory, are unconditional, and can use any of the MC68000
addressing modes to specify the destination.</p>
<p>The MC68000 has a flexible conditional branching instruction, referred to as a <i>Bcc instruction</i>,
in which the letters cc denote a variety of conditions that can be
specified. There are 14 different conditions, including such things as
greater than (BGT), less than or equal to (BLE), equal (BEQ), overflow
(BVS), and low or same (BLS); a complete list is given in table 1. The
BRA instruction is not conditional but always forces the branch to
occur.</p>
<hr>
<p><b>Table 1:</b> <i>Conditional tests for the Bcc and DBcc groups of
instructions. By substituting the letters in the first column for the
letters cc, you can construct as many as 16 Bcc (branch on condition)
and DBcc (test condition, decrement, and branch) instructions; for
example, BHI branches if both the carry and zero bits in the status
register are cleared. The third column indicates that the branch will
take place if the expression evaluates to "true"; "~" indicates a
logical NOT operation, "^" indicates a logical AND operation, while "v"
indicates a logical OR operation. The same conditions are available to
another instruction group, Scc, which sets or clears all the bits of a
given byte based on the condition being evaluated.</i></p>
<pre> Mnemonic    Condition Description         Flags Tested
    T          true                             1
    F          false                            0
    HI         high                           ~C^~Z
    LS         low or same                     C+Z
    CC         carry clear                     ~C
    CS         carry set                        C
    NE         not equal                       ~Z
    EQ         equal                            Z
    VC         overflow clear                  ~V
    VS         overflow set                     V
    PL         plus                            ~N
    MI         minus                            N
    GE         greater or equal            (N^V)v(~N^~V)
    LT         less than                  (N^~V)v(~N^V)
    GT         greater than             (N^V^~Z)v(~N^~V^~Z)
    LE         less or equal            Zv(N^~V)v(~N^V)</pre>
<hr>
<p>You cause branching by the addition of some value to the program
counter (PC). Branch instructions include an 8- or 16-bit signed
displacement value that you add to the program counter. Because the
displacement is a signed number, it can cause either a forward or
backward branch. If the condition being tested evaluates to "true," the
MC68000 will take the branch; if it is not, it will execute the next
instruction in sequence.</p>
<p>Even though all MC68000 instructions are multiples of 16 bits and
must be aligned on word boundaries (i.e., start on even addresses), the
MC68000 interprets the displacement in all branching operations to be a
byte count, not a word count. This is done to give the machine maximum
flexibility, while still providing the most opportunity for future
growth. Limiting the machine to word offsets would have prevented any
future MC68000-family processor from having instructions that could be
misaligned (i.e., did not start on a word boundary) or be multiples of
8 bits. Since the flexibility to have misaligned instructions still
exists, it makes sense to follow the natural byte-oriented addressing
of the MC68000. A 16-bit offset gives an addressing range of -32,768
bytes to +32,767 bytes, not the puny 8-bit computer range of -128 to
+127 bytes.</p>
<p>Versions of the jump and branch instructions also exist for
subroutine calls. You can branch to a subroutine (BSR) with a
displacement value, or you can jump to the subroutine (JSR) by
specifying the absolute address. Subroutine calls save the return
address (the current value of the program counter) on the system stack
before transferring control to the subroutine; the return address is
removed from the stack and restored to the program counter when the
MC68000 executes the RTS (return-from-subroutine) instruction.</p>
<p>Sometimes you will want to save and restore the condition codes that
existed just before the subroutine was called. This is easy enough to
do with the MOVE SR,-(A7) instruction, which pushes the status register
onto the system stack (pointed to by register A7). You can also save
selected registers with a single MOVEM instruction (discussed last
month). At the close of the subroutine, you can use a MOVEM instruction
to restore the saved registers and then use an RTR instruction (return
and restore condition codes) to return and restore the saved condition
codes in one operation.</p>
<h3>Looping and String Constructs</h3>
<p>Many times, a backward branch is used to create a <i>programming loop</i>,
which is a very important part of programming because it allows
operations to be repeated until a desired state or condition is
reached. Although the looping constructs that most people are familiar
with provide for a loop that ends with a given condition or one that
ends after a certain number of iterations, a loop that can end by <i>either</i>
means is often very useful. The double condition allows a loop to be
performed until a given condition is met while ensuring that the loop
does not process invalid data (in the case of, say, a string operation
that reaches the end of the data without meeting the condition) or run
forever (in the case of a numerical analysis algorithm that never
converges to a given minimum tolerance).</p>
<p>The MC68000 has just the instruction for this kind of loop. The <i>decrement-counter-and-branch-conditionally</i>
instruction (DBcc) uses any data register as a counter and branches
based on both the evaluated condition and the data-register value. A
DBcc instruction causes the following sequence of events. First, the
MC68000 checks to see if the stated condition is met; if so, execution
continues with the <i>next</i> instruction, thus ending the loop. If
the condition is not met, the specified register is decremented by 1.
If the resulting value is -1, the loop is again ended by having the
execution continue with the next intruction; otherwise, the branch to
the top of the loop occurs.</p>
<p>Note that the DBcc instruction tests the register for a value of -1.
At first, this might seem odd, but there is a very good reason for it.
Most looping constructs require extra steps to ensure that the loop can
execute zero times when needed <i>and</i> that the loop tests for the desired condition <i>before</i>
executing a given iteration. By having the loop entered just before the
DBcc instruction (at the end of the loop) and by designing the DBcc
instructions so that they end the loop on a value of -1 instead of 0,
you create a loop that meets both of the above conditions without being
burdened by an explicit second test. As an added bonus, a simple
conditional branch instruction (using the same condition as the DBcc
instruction) enables you to determine whether the program exited the
loop because of the iteration counter or the condition.</p>
<p>The DBcc instruction provides a huge set of string operations,
especially in conjunction with the predecrement and postincrement
addressing modes. By using the appropriate MOVE instruction, for
example:
</p>
<pre>        MOVE Dn,(An)+;
        MOVE (An)+,(An)+;
        MOVE -(An),-(An);
     or MOVE (An)+,-(An)</pre>
<p>followed by a DBRA instruction, you can have the MC68000 fill a
block of memory, copy strings, and reverse strings. CMPM -(An),-(An)
with DBNE compares two strings, while CMP Dn,-(An) with DBEQ searches a
string for a pattern match. (See part 2, May BYTE, page 342, for an
explanation of this address mode notation.) Multi-instruction loops can
make very powerful string operations quite simple.</p>
<p>You can see the real beauty of the DBcc instruction in the
assembly-language program of listing 1, which translates a string of
characters until a terminating character shows up or the end of the
string is reached. Register D3 has the string length in it, while
register D4 contains the terminating character you're looking for.
Register A1 points to the string, while the translation table (which is
found some distance from this code) has its location placed in register
A2. The routine in listing 1 runs very quickly and demonstrates the
power that results from a combination of versatile instructions and
various addressing modes.
</p><hr>
<p><b>Listing 1:</b> <i>A string translation program that uses the DBEQ
instruction to end a loop based on either of two conditions: end of
string (as determined by the string length, given in register D3) or
discovery of a termination character (stored in register D4). This
program translates a string character by character according to the
character values stored in TABLE. For a given character, its value
(stored in register D0) is used as an index into TABLE (pointed to by
register A2); the actual translation takes place at LOOP.</i></p>
<pre>         MOVEQ   #$13,DR         load termination character into register
         MOVE    #COUNT,D3       load string length
         MOVE.L  #STRING,A1      load string beginning
         LEA     *+TABLE,A2      offset to conversion table
         CLR     D0              prepare index for word
         BRA     POOL            start translation
 LOOP    MOVE.B  0(A2,D0),(A1)+  translate and store result
 POOL    MOVE.B  (A1),D0         load next character
         CMP.B   D4,D0           termination character found?
         DBEQ    D3,LOOP         if not and not end of string, branch

 Execution time where <b>n</b> bytes are translated:
 72 + (40 * <b>n</b>) clocks = 649 &#181;sec for 128 bytes at 8 MHz</pre>
<hr>
<h3>High-Level Language Aids</h3>
<p>Many high-level languages, such as Pascal, use sophisticated
programming concepts that can be enhanced by the use of reentrant and
recursive programming and subroutines with local variable areas. The
MC68000 has the facilities to support these techniques.</p>
<p>You can enter reentrant code at any time by several execution
processes, and it will return correct results to all of them. This is
very important for interrupt routines that may interrupt themselves
before completion. Only reentrant code will correctly execute the
interrupt routine the second time, then return to its interrupted
version and correctly execute it. The MC68000 instruction set makes
reentrant programming easy.</p>
<p>Recursive programs are those that can call themselves. An example of
such a program might draw a straight line between two points by
repeatedly plotting the midpoint of the line, then calling itself to
operate on the two line segments created by the new point. Recursive
programs are created to solve complex algorithms with relatively small
amounts of code. Their disadvantages include slow execution and heavy
use of the stack (or some other area) for storing each level's set of
temporary variables. Of course, the MC68000 designers included special
instructions to make this task easier, LINK and UNLK (unlink).</p>
<p>LINK and UNLK allow subroutines to allocate part of the stack for
the storage of local variables quickly and easily. Often, a programmer
needing to refer to variables associated with a given subroutine call
will decrement the stack pointer to reserve an area of memory for such
use ("decrement" because stacks usually "grow" downward in memory) and
save the address of the top edge of this area as a reference point;
this address is called a <i>frame pointer</i> (FP) and is a value
that, on the MC68000, is stored in one of the seven address registers
A0 through A6. The stack pointer, of course, will move up and down
during the execution of a subroutine as stack operations are performed.
The stable frame pointer always gives a good reference point to the
variables, while the stack pointer would give a wildly varying
reference to those same variables. Now let's look at a good method for
going into a new routine.</p>
<p>To show how the LINK and UNLK instructions help give the programmer
access to local variable areas, let's look at the example of figure 1.
(Remember that the frame pointer is actually an address register that
is designated by the programmer for this use.) Assume that you are in
subroutine A, which has its own local variable area, pointed to by the
frame pointer. Before subroutine A calls subroutine B, it first places
parameters on top of the stack; see figure 1a. After the subroutine
call to B, the return address to A is pushed onto the stack (figure
1b). The LINK instruction contains the name of an address register that
is to be taken as the frame register and a displacement that indicates
the amount of memory to be saved for local variables. When it is
executed, three things happen (figures 1c-1e): the contents of the
frame pointer (pointing to a stack location containing the previous
frame pointer) are pushed onto the stack, the frame pointer itself is
made identical to the stack pointer, and the stack pointer is changed
by the displacement given in the instruction. (The displacement is a
signed value and must be negative to save local variable space -- if it
is positive, you will lose information from the stack.) As shown in
figure 1e, the stack pointer points to the top of the stack, and the
frame pointer points to one word below the subroutine B local variable
area. When the UNLK instruction is executed, the process is reversed
(figure 1f), leaving subroutine B ready to execute an RTS instruction
and return control to subroutine A.</p>
<hr>
<p><b>Figure 1:</b> <i>Use of the LINK and UNLK (unlink) instructions,
both of which help the assembly-language programmer manage memory areas
to be used for local variables in subroutines. See text for details.</i></p>
<pre>         (A)                           (B)
         BEFORE                        AFTER
         EXECUTION                     EXECUTION
         OF JSR B                      OF JSR B


       /                 /           /                 /
       |                 |           |                 |
       |                 |           |                 |
       |-----------------|           |-----------------|
       |                 |           |                 |
       |                 |           |                 |
       |                 |           |                 |
       |                 |           |                 |
       |-----------------|           |-----------------|
       |                 |           |                 |
       |                 |           |                 |
       |-----------------|           |-----------------|
       |                 |     SP -&gt; | RETURN ADDRESS  |
       |                 |           | TO SUBROUTINE A |
       |-----------------|           |-----------------|
 SP -&gt; | PARAMETERS FOR  |           |                 |
       | SUBROUTINE B    |           |                 |
       |-----------------|           |-----------------|
       | SPACE FOR       |           |                 |
       | SUBROUTINE A    |           |                 |
       | LOCAL VARIABLES |           |                 |
       |-----------------|           |-----------------|
 FP -&gt; | PREVIOUS FP     |     FP -&gt; |                 |
       |-----------------|           |-----------------|
       |                 |           |                 |
       |                 |           |                 |
       /                 /           /                 /



         (C)                           (D)
         AFTER                         AFTER
         STEP 1                        STEP 2
         OF LINK                       OF LINK
         INSTRUCTION                   INSTRUCTION

       /                 /           /                 /
       |                 |           |                 |
       |                 |           |                 |
       |-----------------|           |-----------------|
       |                 |           |                 |
       |                 |           |                 |
       |                 |           |                 |
       |                 |           |                 |
       |-----------------|           |-----------------|
 SP -&gt; | POINTER TO      |     SP -&gt; | POINTER TO      |
       | SUBROUTINE A FP |     FP -&gt; | SUBROUTINE A FP |
       |-----------------|           |-----------------|
       | RETURN ADDRESS  |           | RETURN ADDRESS  |
       | TO SUBROUTINE A |           | TO SUBROUTINE A |
       |-----------------|           |-----------------|
       |                 |           |                 |
       |                 |           |                 |
       |-----------------|           |-----------------|
       |                 |           |                 |
       |                 |           |                 |
       |                 |           |                 |
       |-----------------|           |-----------------|
 FP -&gt; |                 |           |                 |
       |-----------------|           |-----------------|
       |                 |           |                 |
       |                 |           |                 |
       /                 /           /                 /



         (E)                           (F)
         AFTER                         AFTER
         STEP 3                        UNLK
         OF LINK
         INSTRUCTION

       /                 /           /                 /
       |                 |           |                 |
       |                 |           |                 |
       |-----------------|           |-----------------|
 SP -&gt; | SPACE FOR       |           |                 |
       | SUBROUTINE B    |           |                 |
       | LOCAL           |           |                 |
       | VARIABLES       |           |                 |
       |-----------------|           |-----------------|
 FP -&gt; | POINTER TO      |           |                 |
       | SUBROUTINE A FP |           |                 |
       |-----------------|           |-----------------|
       | RETURN ADDRESS  |     SP -&gt; | RETURN ADDRESS  |
       | TO SUBROUTINE A |           | TO SUBROUTINE A |
       |-----------------|           |-----------------|
       |                 |           |                 |
       |                 |           |                 |
       |-----------------|           |-----------------|
       |                 |           |                 |
       |                 |           |                 |
       |                 |           |                 |
       |-----------------|           |-----------------|
       |                 |     FP -&gt; |                 |
       |-----------------|           |-----------------|
       |                 |           |                 |
       |                 |           |                 |
       /                 /           /                 /</pre>
<hr>
<h3>Address Calculation in Hardware</h3>
<p>Most microprocessor operations deal either with data or program
control. Most also use memory addresses and, in the case of the
MC68000, have some rather sophisticated means of generating those
addresses. But the addresses are used by the instruction only to get to
the data or program location; the address itself is never available to
the programmer and is often lost by the end of the instruction.
However, it is sometimes the address itself that you need in your
program. The MC68000 has two instructions that help you to get just the
address, without using it to fetch any data. By having the MC68000
calculate the address itself (instead of writing a sequence of
assembly-language instructions to do the same), you can do the
calculation much faster without tying up either memory or registers.</p>
<p>The load-effective-address (LEA) and push-effective-address (PEA)
instructions calculate a given effective address and place it either in
any address register (LEA) or on the stack (PEA). You can calculate the
effective address by using any available addressing mode with any of
the appropriate registers. The LEA and PEA instructions can be useful
when you are running position-independent code. Sometimes to take
advantage of an addressing mode that runs more quickly than, say, the
programcounter-relative addressing mode, you may want to calculate the
address using LEA and access that area of memory by addressing
indirectly through the address register in which the LEA instruction
left the calculated address. PEA and LEA are also useful for passing
pointers of data to other routines or placing them in memory.
Sometimes, it's helpful to verify that an effective address is correct
or at least in range. Without these two instructions, it would be
extremely difficult to use processor-generated addresses.</p>
<h3>Instructions for Shared Resources</h3>
<p>Systems with more than one microprocessor running at a time are
often designed to share some resources, e.g., memory, buffers, I/O,
tasks, and so on. For this to happen, the programs running on the
microprocessors must have a secure method of determining which
processor has rights to a certain part of memory, a buffer, I/O, or a
task. The MC68000 has an instruction, TAS (test and set), that makes
such allocation of resources between multiprocessors simple and secure.</p>
<p>The key to this instruction is that it is <i>indivisible</i>, i.e.,
it can lock out all accesses to the designated addressing location
until work on the location is complete. The test-and-set instruction
tests a given byte, sets the negative (N) and zero (Z) status register
bits accordingly, and then sets the most significant bit of the byte to
1.</p>
<p>In most cases, the microprocessor uses the TAS instruction as
follows: It chooses a given byte to represent the status of a shared
resource (this byte is often called a <i>semaphore</i>). If the TAS
instruction shows the byte to be negative (if its most significant bit
is 1), the querying microprocessor knows that the resource is in use.
The processor can then either retest the semaphore byte until it shows
the resource is available, or it can go about some other task. If the
TAS instruction shows the byte to be positive (most significant bit is
0), the microprocessor knows the resource is free. Because the TAS
instruction immediately sets the most significant bit to 1 (and because
the instruction cannot be interrupted before completion), all the
microprocessors with access to the semaphore byte have correct
information about the shared resource. The microprocessor that has
access to the shared resource has the responsibility of clearing the
most significant bit when it is finished.</p>
<p>The only reason this process can work effectively is that the
indivisible read-modify-write bus cycle (a special bus cycle) that
accompanies the TAS instruction prevents, with hardware signals, any
other device from accessing the semaphore byte between the time the TAS
reads it and the time it is through setting the bit in it. This means
that no two processors can read a semaphore byte and both be told that
the resource is available. Thus, a secure way exists for software to
determine the availability of shared resources in a multiprocessor
MC68000 system.</p>
<h3>Supervisor and User Modes</h3>
<p>The MC68000 executes instructions at one of two operating or privilege levels. The upper level, called the <i>supervisor level</i>,
provides a protected environment for the operating system to run in,
isolating it and its resources from the less trustworthy user code.
After a reset operation, the MC68000 begins running in the supervisor
mode, in which the operating system and all interrupt routines are also
running. The lower level, called the <i>user</i> level, is where most application programs execute and, therefore, where the processor usually spends most of its time.</p>
<p>The only controlled way to get from the supervisor level to the user
level is by changing the S/U (supervisor/user) status bit (bit 13) in
the processor status register. This is how the operating system
switches to begin a user-level program. Should an interrupt be handled
in the middle of a user-level routine, the interrupt routine will run
at the supervisor level, but upon return to the interrupted routine,
the MC68000 will return to the user level.</p>
<p>User-level programs are guaranteed to go to the operating system
only through one of the 16 TRAP number n instructions. You can view
these instructions as supervisor calls; they immediately transfer
control to a specific routine. Upon completion of the TRAP routine, the
processor will usually return to the original user-level routine to
continue. Thus, there are 16 different supervisor trap instructions,
which, along with other types of trap instructions, are listed in table
2.</p>
<hr>
<p><b>Table 2:</b> <i>Supervisor trap types and their causes.</i></p>
<pre> <b>Type of Trap            Cause</b>

 address error           word or long-word access to an odd address

 illegal instruction     no valid instruction exists for this op code
                         (op codes starting with "1010..." and
                         "1111..." generate other traps; see below)

 zero divide             attempt to divide by zero

 CHK instruction         CHK instruction failed
                         (operand out of bounds)

 TRAPV instruction       overflow has occurred (V bit set)

 privilege violation     attempt to execute a privileged
                         instruction while in the user mode

 trace                   an instruction has just ended and
                         the T status register bit is set

 line 1010 emulator      attempt to execute an op code
                         that starts with "1010"

 line 1111 emulator      attempt to execute an op code
                         that starts with "1111"

 TRAP <i>n</i> instruction      Trap <i>n</i> instruction executed (<i>n</i>=0,1,...,15)</pre>
<hr>
<p>Many other means of getting to the supervisor level of execution
exist, but they are either conditional (like error traps) or
asynchronous (like interrupts). Regardless, all traps are handled
similarly by the supervisor. Any trap causes the processor to save the
old program counter and status register on the supervisor stack. Then
it will go to its external vector table and get a value, appropriate
for the cause of the trap, to load into the program counter. This
allows each type of trap to have a separate handling routine to correct
the problem causing the trap and return to the original program.</p>
<p>Some of these other trap forms are intentionally conditional.
Depending upon whether the overflow (V) condition bit is set, one
instruction, TRAPV, either does nothing or causes a trap to occur,
which forces the MC68000 into the supervisor state. This enables the
program to handle all overflow conditions uniformly in a single
operating-system-level routine. Another such instruction is the check
(CHK) instruction, which verifies that the contents of any data
register is greater than 0 but less than a specified bound. If it is
within the limits, then nothing happens and the next instruction is
run. If it is outside the bounds, then program control jumps indirectly
through the vector table to a certain trap routine for handling. This
gives the programmer an easy way to check whether an array index is
within the proper bounds for that array. In addition, attempts to
divide by 0 and access misaligned data (words or long words in memory
on odd-byte addresses) will cause trap routines to be executed.</p>
<h3>Handling Illegal and Unimplemented Op Codes</h3>
<p>To allow room for future expansion of the MC68000, designers did not
use all of the possible bit patterns of the 16-bit op codes. Other
microprocessors try to execute undefined op codes, often with
disastrous results that cause you to lose control of the computer or
even lose valuable work. To assure a completely foolproof system in the
face of undefined op codes, the MC68000 refuses to execute any illegal
instruction and, instead, executes a specified trap routine for
corrective action.</p>
<p>To enable programmers to add whole blocks of new instructions to
MC68000 processors, designers left two subgroups of possible op codes
unimplemented. Any 16-bit op code beginning with binary 1010 or 1111
was left without definition in the MC68000. Attempts to execute either
of these categories of op codes, even though they could be considered
illegal instructions, are trapped separately. They cause either a
line-1010-emulator or a line-1111-emulator trap routine to execute,
enabling the programmer to emulate in software functions that are not
implemented in the processor chip of the system. Currently, the 1111 op
codes are defined mostly as floating-point instructions and so could be
emulated on the MC68000. The 1010 op codes are still reserved for use
in processors beyond the MC68020.</p>
<h3>Privileged Instructions</h3>
<p>Privileged instructions have a special characteristic -- they can be
executed only while the processor is running at the supervisor level.
Attempts to run them at the user level force privilege-violation traps
to occur, allowing the supervisor to take whatever action it thinks
suitable.</p>
<p>The privileged instructions are listed in table 3 and are mostly
self-explanatory. These instructions are restricted because they modify
or control resources or services that must be under the control of the
operating system. Many of these instructions modify the upper portion
of the status register (SR), which contains the S/U supervisor bit, the
interrupt mask, and a trace-mode switch. Such resources are not meant
to be in the hands of the users, but maintained by the supervisor; this
is why they are restricted.</p>
<hr>
<p><b>Table 3:</b> <i>Privileged instructions in the MC68000.</i></p>
<pre> STOP
 RESET
 RTE
 MOVE (when moving a word to the
       status register)
 MOVE USP
 AND, EOR, or OR (when combining an
                  immediate value with the
                  status register)</pre>
<hr>
<p>Another supervisor-privileged resource is the <i>supervisor stack pointer</i> (SSP). This pointer is visible (as address register A7) only when the MC68000 is running at the supervisor level, just as the <i>user stack pointer</i>
(USP) is visible (as register A7) only when the MC68000 is running at
the user mode. However, when the operating system is ready to pull in a
new user-level task, it needs to be able to access the hidden USP to
initialize it. This is done with a special, privileged MOVE USP
instruction.</p>
<p>The STOP instruction halts processor execution of further
instructions, while waiting for an interrupt, a trace exception, or a
reset to initiate new activity. The instruction also loads the status
register with an immediate 16-bit value, allowing the programmer to
enable certain interrupts before stopping the microprocessor. Only the
supervisor can initiate this type of operation because, in a user's
hands, the operation might throw off all sorts of operating-system
timing integrity (such as time-slice clock signals) and generally
brings the system to an irrecoverable halt. Also, the instruction must
be restricted because it affects the entire status register.</p>
<p>The RESET instruction is a unique and powerful operation. Its
execution pulses the reset line on the MC68000 without resetting the
processor itself. You use this instruction typically after a
catastrophic failure, from which the operating system is trying to
recover on its own. It enables the operating system to initialize its
external environment (i.e., reset the entire system except for the
microprocessor) without forcing itself into a complete restart.
Obviously, this instruction's power makes it inappropriate for the user
level.</p>
<p>One final privileged instruction is the RTE (return-from-exception)
instruction. An exception is anything that causes the microprocessor to
perform an operation other than the next normal instruction. Interrupts
and traps, then, are exceptions. The RTE is similar to the
return-from-interrupt instruction of most microprocessors. It basically
reloads both the program counter and the status register with the
values from the top of the stack. Because all exceptions force the
processor to execution in the supervisor mode, the RTE instruction will
be executed only in that mode; this makes it a privileged instruction.</p>
<p>Note, once again, that privileged instructions can be executed from
only the supervisor level of operation, where the operating system
usually resides. The two different levels of privilege and the
restricted use of privileged instructions allow you to build systems
that prevent user-level application programs from, inadvertantly or
otherwise, running rampant through operating-system code and data.</p>
<h3>Conclusion</h3>
<p>As you have seen in previous installments of this article, the
MC68000 architecture is really designed with the programmer in mind.
The MC68000 branch and jump instructions give you complete control over
program flow and simplify often-used looping and string-movement
constructs. The link and unlink instructions make it easier for you to
create modular programs that use local variables. Other instructions
carry out complex address calculations quickly, help mediate the use of
shared resources, provide for the data integrity of the operating
system, and allow recovery from errors under program control. In
addition, planners designed the architecture and instruction set with
far greater things in mind and made the set easy to expand to more
powerful and more comprehensive functions. And all this has been done
with a processor for which performance was a primary criterion.</p>
<p>Once you learn a few general concepts of programming the MC68000,
coding an application comes easily. Pick up an MC68000 user's manual
and a similar guide for any other 16-bit microprocessor. Then spend an
hour or two learning each. Code a short program or two, and compare
just how easy the MC68000 is to work with. And if you choose to write
code for a larger program, you will find your task to be simple
regardless of program size.</p>
<p>The MC68000 was designed to be a programmer's instrument through
which programmers and system designers could use their creativity to
engineer a system to fit the application instead of having to figure
out some trick to get the microprocessor to perform the needed task. We
at Motorola believe that using the right tool gets a job done faster
with fewer mistakes, and the MC68000 is such a tool.</p>
<hr>
<p><b>About the Author</b><br>Thomas Starnes is an electrical engineer
who has spent the last five years helping to plan the direction of the
MC68000 family of processor products for Motorola.</p>
</body></html>